home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / r_main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-18  |  45.9 KB  |  1,977 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // r_main.c
  21. #include "r_local.h"
  22.  
  23. void R_Clear (void);
  24.  
  25. viddef_t    vid;
  26.  
  27. int GL_TEXTURE0, GL_TEXTURE1;
  28.  
  29. model_t        *r_worldmodel;
  30.  
  31. float        gldepthmin, gldepthmax;
  32.  
  33. glconfig_t    gl_config;
  34. glstate_t    gl_state;
  35.  
  36. image_t        *r_notexture;        // use for bad textures
  37. image_t        *r_particletexture;    // little dot for particles
  38. image_t        *r_smoketexture;    // for smoke, etc...
  39. image_t        *r_explosiontexture;
  40. image_t        *r_bloodtexture;
  41. image_t        *r_pufftexture;
  42. image_t        *r_blastertexture;
  43. image_t        *r_bflashtexture;
  44. image_t        *r_leaderfieldtexture;
  45. image_t     *r_shelltexture;    // c14 added shell texture
  46.  
  47. entity_t    *currententity;
  48. model_t        *currentmodel;
  49.  
  50. cplane_t    frustum[4];
  51.  
  52. int            r_visframecount;    // bumped when going to a new PVS
  53. int            r_framecount;        // used for dlight push checking
  54.  
  55. int            c_brush_polys, c_alias_polys;
  56.  
  57. float        v_blend[4];            // final blending color
  58.  
  59. gparticle_t gparticles[MAX_PARTICLES];
  60. int            num_gparticles;
  61.  
  62. void GL_Strings_f( void );
  63.  
  64. //
  65. // view origin
  66. //
  67. vec3_t    vup;
  68. vec3_t    vpn;
  69. vec3_t    vright;
  70. vec3_t    r_origin;
  71.  
  72. float    r_world_matrix[16];
  73.  
  74. //
  75. // screen size info
  76. //
  77. refdef_t    r_newrefdef;
  78.  
  79. int        r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
  80.  
  81. cvar_t    *r_norefresh;
  82. cvar_t    *r_drawentities;
  83. cvar_t    *r_drawworld;
  84. cvar_t    *r_speeds;
  85. cvar_t    *r_fullbright;
  86. cvar_t    *r_novis;
  87. cvar_t    *r_nocull;
  88. cvar_t    *r_lerpmodels;
  89. cvar_t    *r_lefthand;
  90.  
  91. cvar_t    *r_lightlevel;    // FIXME: This is a HACK to get the client's light level
  92.  
  93. cvar_t    *gl_nosubimage;
  94. cvar_t    *gl_allow_software;
  95.  
  96. cvar_t    *gl_vertex_arrays;
  97.  
  98. cvar_t    *gl_particle_min_size;
  99. cvar_t    *gl_particle_max_size;
  100. cvar_t    *gl_particle_size;
  101. cvar_t    *gl_particle_att_a;
  102. cvar_t    *gl_particle_att_b;
  103. cvar_t    *gl_particle_att_c;
  104.  
  105. cvar_t    *gl_ext_swapinterval;
  106. cvar_t    *gl_ext_palettedtexture;
  107. cvar_t    *gl_ext_multitexture;
  108. cvar_t    *gl_ext_pointparameters;
  109. cvar_t    *gl_ext_compiled_vertex_array;
  110.  
  111. cvar_t    *gl_log;
  112. cvar_t    *gl_bitdepth;
  113. cvar_t    *gl_drawbuffer;
  114. cvar_t  *gl_driver;
  115. cvar_t    *gl_lightmap;
  116. cvar_t    *gl_shadows;
  117. cvar_t    *gl_mode;
  118. cvar_t    *gl_dynamic;
  119. cvar_t  *gl_monolightmap;
  120. cvar_t    *gl_modulate;
  121. cvar_t    *gl_nobind;
  122. cvar_t    *gl_round_down;
  123. cvar_t    *gl_picmip;
  124. cvar_t    *gl_skymip;
  125. cvar_t    *gl_showtris;
  126. cvar_t    *gl_finish;
  127. cvar_t    *gl_clear;
  128. cvar_t    *gl_cull;
  129. cvar_t    *gl_polyblend;
  130. cvar_t    *gl_flashblend;
  131. cvar_t    *gl_playermip;
  132. cvar_t  *gl_saturatelighting;
  133. cvar_t    *gl_swapinterval;
  134. cvar_t    *gl_texturemode;
  135. cvar_t    *gl_texturealphamode;
  136. cvar_t    *gl_texturesolidmode;
  137. cvar_t    *gl_lockpvs;
  138.  
  139. cvar_t    *gl_3dlabs_broken;
  140.  
  141. cvar_t    *vid_fullscreen;
  142. cvar_t    *vid_gamma;
  143. cvar_t    *vid_ref;
  144.  
  145.  
  146. void R_AddGlowEffect (float red, float green, float blue, float radius, vec3_t origin);
  147.  
  148.  
  149. // glow definitions - originally from gl_rmain.c
  150. #define MAX_GLOWS 2048
  151. int num_glows;
  152.  
  153. typedef struct glows_s
  154. {
  155.     float red;
  156.     float green;
  157.     float blue;
  158.     float radius;
  159.     vec3_t origin;
  160. } glows_t;
  161.  
  162. glows_t glow_effects[MAX_GLOWS];
  163.  
  164. // sin and cos tables from 0 to 1 in 0.0625 increments to speed up glow rendering
  165. // also from gl_rmisc.c and externed in gl_quake.h - i also use them for alias model glows.
  166. float glowcos[17] = 
  167. {
  168.     1.000000,
  169.     0.923879,
  170.     0.707106,
  171.     0.382682,
  172.     -0.000002,
  173.     -0.382686,
  174.     -0.707109,
  175.     -0.923881,
  176.     -1.000000,
  177.     -0.923878,
  178.     -0.707103,
  179.     -0.382678,
  180.     0.000006,
  181.     0.382689,
  182.     0.707112,
  183.     0.923882,
  184.     1.000000,
  185. };
  186.  
  187.  
  188. float glowsin[17] = 
  189. {
  190.     0.000000,
  191.     0.382684,
  192.     0.707107,
  193.     0.923880,
  194.     1.000000,
  195.     0.923879,
  196.     0.707105,
  197.     0.382680,
  198.     -0.000004,
  199.     -0.382687,
  200.     -0.707110,
  201.     -0.923882,
  202.     -1.000000,
  203.     -0.923877,
  204.     -0.707102,
  205.     -0.382677,
  206.     0.000008,
  207. };
  208.  
  209.  
  210. // this prototype was not required in my original engine
  211. void R_RenderGlowEffects (void);
  212.  
  213. /*
  214. =================
  215. R_CullBox
  216.  
  217. Returns true if the box is completely outside the frustom
  218. =================
  219. */
  220. qboolean R_CullBox (vec3_t mins, vec3_t maxs)
  221. {
  222.     int        i;
  223.  
  224.     if (r_nocull->value)
  225.         return false;
  226.  
  227.     for (i=0 ; i<4 ; i++)
  228.         if ( BOX_ON_PLANE_SIDE(mins, maxs, &frustum[i]) == 2)
  229.             return true;
  230.     return false;
  231. }
  232.  
  233.  
  234. void R_RotateForEntity (entity_t *e)
  235. {
  236.     qglTranslatef (e->origin[0],  e->origin[1],  e->origin[2]);
  237.  
  238.     qglRotatef (e->angles[1],  0, 0, 1);
  239.     qglRotatef (-e->angles[0],  0, 1, 0);
  240.     qglRotatef (-e->angles[2],  1, 0, 0);
  241. }
  242.  
  243. /*
  244. =============================================================
  245.  
  246.   SPRITE MODELS
  247.  
  248. =============================================================
  249. */
  250.  
  251.  
  252. /*
  253. =================
  254. R_DrawSpriteModel
  255.  
  256. =================
  257. */
  258. void R_DrawSpriteModel (entity_t *e)
  259. {
  260.     float alpha = 1.0F;
  261.     vec3_t    point;
  262.     vec3_t        v_forward, v_right, v_up;
  263.     dsprframe_t    *frame;
  264.     float        *up, *right;
  265.     dsprite_t    *psprite;
  266.  
  267.     // don't even bother culling, because it's just a single
  268.     // polygon without a surface cache
  269.  
  270.     psprite = (dsprite_t *)currentmodel->extradata;
  271.  
  272.     e->frame %= psprite->numframes;
  273.  
  274.     frame = &psprite->frames[e->frame];
  275.  
  276.     AngleVectors (currententity->angles, v_forward, v_right, v_up);
  277.     up = v_forward;
  278.     right = v_right;
  279.  
  280.     GL_Bind (currentmodel->skins[e->frame]->texnum);
  281.     
  282.     alpha = 0.6;
  283.     qglDepthMask( GL_FALSE );
  284.     qglEnable( GL_BLEND );
  285.     qglBlendFunc (GL_SRC_ALPHA, GL_ONE);
  286.     GL_TexEnv( GL_MODULATE );
  287.     qglBegin (GL_QUADS);
  288.  
  289.     qglColor4f( 1, 1, 1, alpha );
  290.     
  291.     qglTexCoord2f (0, 1);
  292.     VectorMA (e->origin, -frame->origin_y, up, point);
  293.     VectorMA (point, -frame->origin_x, right, point);
  294.     qglVertex3fv (point);
  295.  
  296.     qglTexCoord2f (0, 0);
  297.     VectorMA (e->origin, frame->height - frame->origin_y, up, point);
  298.     VectorMA (point, -frame->origin_x, right, point);
  299.     qglVertex3fv (point);
  300.  
  301.     qglTexCoord2f (1, 0);
  302.     VectorMA (e->origin, frame->height - frame->origin_y, up, point);
  303.     VectorMA (point, frame->width - frame->origin_x, right, point);
  304.     qglVertex3fv (point);
  305.  
  306.     qglTexCoord2f (1, 1);
  307.     VectorMA (e->origin, -frame->origin_y, up, point);
  308.     VectorMA (point, frame->width - frame->origin_x, right, point);
  309.     qglVertex3fv (point);
  310.     
  311.     qglEnd ();
  312.  
  313.     qglDisable (GL_ALPHA_TEST);
  314.     GL_TexEnv( GL_REPLACE );
  315.     qglDisable( GL_BLEND );
  316.     qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  317.     qglDepthMask( 1 );
  318.     qglColor4f( 1, 1, 1, 1 );
  319. }
  320.  
  321. //==================================================================================
  322.  
  323. /*
  324. =============
  325. R_DrawNullModel
  326. =============
  327. */
  328. void R_DrawNullModel (void)
  329. {
  330.     vec3_t    shadelight;
  331.     int        i;
  332.  
  333.     if ( currententity->flags & RF_FULLBRIGHT )
  334.         shadelight[0] = shadelight[1] = shadelight[2] = 1.0F;
  335.     else
  336.         R_LightPoint (currententity->origin, shadelight);
  337.  
  338.     qglPushMatrix ();
  339.     R_RotateForEntity (currententity);
  340.  
  341.     qglDisable (GL_TEXTURE_2D);
  342.     qglColor3fv (shadelight);
  343.  
  344.     qglBegin (GL_TRIANGLE_FAN);
  345.     qglVertex3f (0, 0, -16);
  346.     for (i=0 ; i<=4 ; i++)
  347.         qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
  348.     qglEnd ();
  349.  
  350.     qglBegin (GL_TRIANGLE_FAN);
  351.     qglVertex3f (0, 0, 16);
  352.     for (i=4 ; i>=0 ; i--)
  353.         qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
  354.     qglEnd ();
  355.  
  356.     qglColor3f (1,1,1);
  357.     qglPopMatrix ();
  358.     qglEnable (GL_TEXTURE_2D);
  359. }
  360.  
  361. /*
  362. =============
  363. R_DrawEntitiesOnList
  364. =============
  365. */
  366. void R_DrawEntitiesOnList (void)
  367. {
  368.     int        i;
  369.  
  370.     if (!r_drawentities->value)
  371.         return;
  372.  
  373.     // draw non-transparent first
  374.     for (i=0 ; i<r_newrefdef.num_entities ; i++)
  375.     {
  376.         currententity = &r_newrefdef.entities[i];
  377.         if (currententity->flags & RF_TRANSLUCENT)
  378.             continue;    // solid
  379.  
  380.         if ( currententity->flags & RF_BEAM )
  381.         {
  382.             R_DrawBeam( currententity );
  383.         }
  384.         else
  385.         {
  386.             currentmodel = currententity->model;
  387.             if (!currentmodel)
  388.             {
  389.                 R_DrawNullModel ();
  390.                 continue;
  391.             }
  392.             switch (currentmodel->type)
  393.             {
  394.             case mod_alias:
  395.                 R_DrawAliasModel (currententity);
  396.                 break;
  397.             case mod_brush:
  398.                 R_DrawBrushModel (currententity);
  399.                 break;
  400.             case mod_sprite:
  401.                 R_DrawSpriteModel (currententity);
  402.                 break;
  403.             default:
  404.                 Com_Error(ERR_DROP, "Bad modeltype");
  405.                 break;
  406.             }
  407.         }
  408.     }
  409.  
  410.     // draw transparent entities
  411.     // we could sort these if it ever becomes a problem...
  412.     qglDepthMask (0);        // no z writes
  413.     for (i=0 ; i<r_newrefdef.num_entities ; i++)
  414.     {
  415.         currententity = &r_newrefdef.entities[i];
  416.         if (!(currententity->flags & RF_TRANSLUCENT))
  417.             continue;    // solid
  418.  
  419.         if ( currententity->flags & RF_BEAM )
  420.         {
  421.             R_DrawBeam( currententity );
  422.         }
  423.         else
  424.         {
  425.             currentmodel = currententity->model;
  426.  
  427.             if (!currentmodel)
  428.             {
  429.                 R_DrawNullModel ();
  430.                 continue;
  431.             }
  432.             switch (currentmodel->type)
  433.             {
  434.             case mod_alias:
  435.                 R_DrawAliasModel (currententity);
  436.                 break;
  437.             case mod_brush:
  438.                 R_DrawBrushModel (currententity);
  439.                 break;
  440.             case mod_sprite:
  441.                 R_DrawSpriteModel (currententity);
  442.                 break;
  443.             default:
  444.                 Com_Error (ERR_DROP, "Bad modeltype");
  445.                 break;
  446.             }
  447.         }
  448.     }
  449.     qglDepthMask (1);        // back to writing
  450.  
  451. }
  452.  
  453. /*
  454. ** GL_DrawParticles
  455. **
  456. */
  457. void GL_DrawParticles( int num_particles, gparticle_t particles[], const unsigned colortable[768])
  458. {
  459.     const gparticle_t *p;
  460.     int                i;
  461.     vec3_t            corner[4], up, right, pup, pright;
  462.     float            scale;
  463.     byte            color[4], oldcolor[4];
  464.     int                oldtype;
  465.     int                texnum, blenddst, blendsrc;
  466.     float            *corner0 = corner[0];
  467.     
  468.     if ( !num_particles )
  469.         return;
  470.  
  471.     qglDepthMask( GL_FALSE );         // no z buffering
  472.     qglEnable( GL_BLEND);
  473.     GL_TexEnv( GL_MODULATE ); 
  474.  
  475.     for ( p = particles, i=0, oldtype=-1 ; i < num_particles ; i++,p++)
  476.     {
  477.         switch (p->type)
  478.         {
  479.             case PARTICLE_EXPLOSION:
  480.                 texnum = r_explosiontexture->texnum;
  481.                 scale = 4 + (rand()&7);
  482.                 *(int *)color = colortable[0xe0];
  483.                 blendsrc = GL_SRC_ALPHA;
  484.                 blenddst = GL_ONE;
  485.                 break;
  486.  
  487.             case PARTICLE_GREEN_BLOOD:
  488.                 texnum = r_bloodtexture->texnum;
  489.                 scale = 3;
  490.                 *(int *)color = colortable[0xd0]; 
  491.                 blendsrc = GL_SRC_ALPHA;
  492.                 blenddst = GL_ONE_MINUS_SRC_ALPHA;
  493.                 break;
  494.  
  495.             case PARTICLE_BLASTER:
  496.                 texnum = r_blastertexture->texnum;
  497.                 scale = 4 + (rand()&7);
  498.                 *(int *)color = colortable[0xe0];
  499.                 blendsrc = GL_SRC_ALPHA;
  500.                 blenddst = GL_ONE;
  501.                 break;
  502.  
  503.             case PARTICLE_BLOOD:
  504.                 texnum = r_bloodtexture->texnum;
  505.                 scale = 3;
  506.                 *(int *)color = colortable[0xe8];
  507.                 blendsrc = GL_SRC_ALPHA;
  508.                 blenddst = GL_ONE_MINUS_SRC_ALPHA;
  509.                 break;
  510.  
  511.             case PARTICLE_GUNSHOT:
  512.                 texnum = r_pufftexture->texnum;
  513.                 scale = 4 + (rand()&2);
  514.                 *(int *)color = colortable[15];
  515.                 blendsrc = GL_SRC_ALPHA;
  516.                 blenddst = GL_ONE_MINUS_SRC_ALPHA;
  517.                 break;
  518.  
  519.             case PARTICLE_HEATBEAM:
  520.                 texnum = r_particletexture->texnum;
  521.                 scale = 5 + (rand()&2);
  522.                 *(int *)color = colortable[0xe0];
  523.                 blendsrc = GL_SRC_ALPHA;
  524.                 blenddst = GL_ONE_MINUS_SRC_ALPHA;
  525.                 break;
  526.  
  527.             case PARTICLE_SMOKE2:
  528.                 texnum = r_smoketexture->texnum;
  529.                 scale = 6 + (rand()&7);
  530.                 *(int *)color = colortable[15];
  531.                 blendsrc = GL_SRC_ALPHA;
  532.                 blenddst = GL_ONE_MINUS_SRC_ALPHA;
  533.                 break;
  534.  
  535.             case PARTICLE_SMOKE:
  536.                 texnum = r_smoketexture->texnum;
  537.                 scale = 3;
  538.                 *(int *)color = colortable[15];
  539.                 blendsrc = GL_SRC_ALPHA;
  540.                 blenddst = GL_ONE_MINUS_SRC_ALPHA;
  541.                 break;
  542.  
  543.             case PARTICLE_GREEN_LASER1:
  544.                 texnum = r_blastertexture->texnum;
  545.                 scale = .2 + (rand()&7);
  546.                 *(int *)color = colortable[0xd0];
  547.                 blendsrc = GL_SRC_ALPHA;
  548.                 blenddst = GL_ONE;
  549.                 break;
  550.  
  551.             case PARTICLE_LEADER_BLAST:
  552.                 texnum = r_blastertexture->texnum;
  553.                 scale = 2 + (rand()&7);
  554.                 *(int *)color = colortable[0xe8];
  555.                 blendsrc = GL_SRC_ALPHA;
  556.                 blenddst = GL_ONE;
  557.                 break;
  558.  
  559.             case PARTICLE_GREEN_LASER2:
  560.                 texnum = r_blastertexture->texnum;
  561.                 scale = .1 + (rand()&5);
  562.                 *(int *)color = colortable[66];
  563.                 blendsrc = GL_SRC_ALPHA;
  564.                 blenddst = GL_ONE;
  565.                 break;
  566.  
  567.             case PARTICLE_BLASTER_MZFLASH:
  568.                 texnum = r_bflashtexture->texnum;
  569.                 scale = 8 + (rand()&7);
  570.                 *(int *)color = colortable[0xe0];
  571.                 blendsrc = GL_SRC_ALPHA;
  572.                 blenddst = GL_ONE;
  573.                 break;
  574.  
  575.             case PARTICLE_LEADER_FIELD:
  576.                 texnum = r_leaderfieldtexture->texnum;
  577. //                scale = scale + 24 + (rand()&2);        // Vic: ???
  578.                 scale = 24 + (rand()&2);
  579.                 *(int *)color = colortable[0xff];
  580.                 blendsrc = GL_SRC_ALPHA;
  581.                 blenddst = GL_ONE;
  582.                 break;
  583.  
  584.             case PARTICLE_STEAM:
  585.                 texnum = r_pufftexture->texnum;
  586.                 scale = 4 + (rand()&2);
  587.                 *(int *)color = colortable[15];
  588.                 blendsrc = GL_SRC_ALPHA;
  589.                 blenddst = GL_ONE;
  590.                 break;
  591.  
  592.             case PARTICLE_LIGHTNING:
  593.                 texnum = r_particletexture->texnum;
  594.                 scale = 1 + (rand()&2);
  595.                 *(int *)color = colortable[0xff];
  596.                 blendsrc = GL_SRC_ALPHA;
  597.                 blenddst = GL_ONE;
  598.                 break;
  599.  
  600.             case PARTICLE_BLASTER_BEAM:
  601.                 texnum = r_particletexture->texnum;
  602.                 scale = 1;
  603.                 *(int *)color = colortable[0xe0];
  604.                 blendsrc = GL_SRC_ALPHA;
  605.                 blenddst = GL_ONE;
  606.                 break;
  607.  
  608.             case PARTICLE_NONE:
  609.                 texnum = r_particletexture->texnum;
  610.                 scale = 1;
  611.                 *(int *)color = colortable[p->color];
  612.                 blendsrc = GL_SRC_ALPHA;
  613.                 blenddst = GL_ONE;
  614.                 break;
  615.  
  616.             default:
  617.                 Com_Printf ( "Unknown particle type: %i\n", p->type);
  618.                 break;
  619.         }
  620.  
  621.         color[3] = p->alpha*255;
  622.  
  623.         if ( 
  624.             p->type != oldtype 
  625.             || color[0] != oldcolor[0] || color[1] != oldcolor[1]
  626.             || color[2] != oldcolor[2] || color[3] != oldcolor[3] )
  627.         {
  628.             if ( oldtype != -1 )
  629.             {
  630.                 qglEnd ();
  631.             }
  632.  
  633.             if ( scale != 1 ) 
  634.             {
  635.                 VectorScale (vup, scale, up);
  636.                 VectorScale (vright, scale, right);
  637.             }
  638.             else
  639.             {
  640.                 VectorCopy (vup, up);
  641.                 VectorCopy (vright, right);
  642.             }
  643.  
  644.             oldtype = p->type;
  645.             oldcolor[3] = color[3];
  646.             VectorCopy ( color, oldcolor );
  647.  
  648.             GL_Bind ( texnum );
  649.             qglBlendFunc ( blendsrc, blenddst );
  650.             qglColor4ubv( color );
  651.             qglBegin ( GL_QUADS );
  652.         }
  653.  
  654.         VectorScale ( right, p->dist, pright );
  655.         VectorScale ( up, p->dist, pup );
  656.         VectorSet (corner[0], 
  657.             p->origin[0] + (pup[0] + pright[0])*(-0.5),
  658.             p->origin[1] + (pup[1] + pright[1])*(-0.5),
  659.             p->origin[2] + (pup[2] + pright[2])*(-0.5));
  660.  
  661.         VectorSet ( corner[1], 
  662.             corner0[0] + pup[0], corner0[1] + pup[1], corner0[2] + pup[2]);
  663.         VectorSet ( corner[2], corner0[0] + (pup[0]+pright[0]), 
  664.             corner0[1] + (pup[1]+pright[1]), corner0[2] + (pup[2]+pright[2]));
  665.         VectorSet ( corner[3], 
  666.             corner0[0] + pright[0], corner0[1] + pright[1], corner0[2] + pright[2]);
  667.  
  668.         qglTexCoord2f( 1, 1 );
  669.         qglVertex3fv( corner[0] );
  670.         
  671.         qglTexCoord2f( 0, 1 );
  672.         qglVertex3fv ( corner[1] );
  673.         
  674.         qglTexCoord2f( 0, 0 );
  675.         qglVertex3fv ( corner[2] );
  676.         
  677.         qglTexCoord2f( 1, 0 );
  678.         qglVertex3fv ( corner[3] );
  679.     }
  680.  
  681.     qglEnd ();
  682.     qglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  683.     qglColor4f( 1,1,1,1 );
  684.     qglDisable(GL_BLEND);
  685.     qglDepthMask( GL_TRUE );    // back to normal Z buffering
  686.     GL_TexEnv( GL_REPLACE );    
  687. }
  688.  
  689. /*
  690. ===============
  691. R_SortParticles
  692. ===============
  693. */
  694. #define R_CopyParticle(a,b) (a.type=b.type,a.alpha=b.alpha,a.color=b.color,a.dist=b.dist,VectorCopy(b.origin,a.origin))
  695.  
  696. static void R_SortParticles (gparticle_t *particles, int Li, int Ri)
  697. {
  698.     int pivot;
  699.     gparticle_t temppart;
  700.     int li, ri;
  701.  
  702. mark0:
  703.     li = Li;
  704.     ri = Ri;
  705.  
  706.     pivot = particles[(Li+Ri) >> 1].type;
  707.     while (li < ri)
  708.     {
  709.         while (particles[li].type < pivot) li++;
  710.         while (particles[ri].type > pivot) ri--;
  711.  
  712.         if (li <= ri)
  713.         {
  714.             R_CopyParticle( temppart, particles[ri] );
  715.             R_CopyParticle( particles[ri], particles[li] );
  716.             R_CopyParticle( particles[li], temppart );
  717.  
  718.             li++;
  719.             ri--;
  720.         }
  721.     }
  722.  
  723.     if ( Li < ri ) {
  724.         R_SortParticles( particles, Li, ri );
  725.     }
  726.     if (li < Ri) {
  727.         Li = li;
  728.         goto mark0;
  729.     }
  730. }
  731.  
  732. /*
  733. ===============
  734. R_DrawParticles
  735. ===============
  736. */
  737. void R_DrawParticles (void)
  738. {
  739.     int                i;
  740.     float            dist;
  741.     gparticle_t        *gp;
  742.     const particle_t *p;
  743.  
  744.     if ( !r_newrefdef.num_particles )
  745.         return;
  746.  
  747.     gp = gparticles;
  748.     num_gparticles = 0;
  749.     for ( p = r_newrefdef.particles, i=0 ; i < r_newrefdef.num_particles ; i++,p++)
  750.     {
  751.         // hack a scale up to keep particles from disapearing
  752.         dist = ( p->origin[0] - r_origin[0] ) * vpn[0] + 
  753.                 ( p->origin[1] - r_origin[1] ) * vpn[1] +
  754.                 ( p->origin[2] - r_origin[2] ) * vpn[2];
  755.  
  756.         if (dist < 0)
  757.             continue;
  758.         else if (dist >= 40)
  759.             dist = 2 + dist * 0.004;
  760.         else
  761.             dist = 2;
  762.  
  763.         gp->alpha = p->alpha;
  764.         gp->color = p->color;
  765.         gp->type = p->type;
  766.         gp->dist = dist;
  767.         VectorCopy ( p->origin, gp->origin );
  768.  
  769.         gp++;
  770.         num_gparticles++;
  771.     }
  772.  
  773.     R_SortParticles ( gparticles, 0, num_gparticles - 1 );
  774.  
  775.     // we are always going to used textured particles!    
  776.     GL_DrawParticles( num_gparticles, gparticles, d_8to24table);
  777. }
  778.  
  779. /*
  780. ============
  781. R_PolyBlend
  782. ============
  783. */
  784. void R_PolyBlend (void)
  785. {
  786.     if (!gl_polyblend->value)
  787.         return;
  788.     if (!v_blend[3])
  789.         return;
  790.  
  791.     qglDisable (GL_ALPHA_TEST);
  792.     qglEnable (GL_BLEND);
  793.     qglDisable (GL_DEPTH_TEST);
  794.     qglDisable (GL_TEXTURE_2D);
  795.  
  796.     qglMatrixMode(GL_PROJECTION);
  797.     qglLoadIdentity ();
  798.     qglOrtho (0, 1, 1, 0, -99999, 99999);
  799.  
  800.     qglMatrixMode(GL_MODELVIEW);
  801.     qglLoadIdentity ();
  802.  
  803.     qglColor4fv (v_blend);
  804.  
  805.     qglBegin (GL_TRIANGLES);
  806.     qglVertex2f (-5, -5);
  807.     qglVertex2f (10, -5);
  808.     qglVertex2f (-5, 10);
  809.     qglEnd ();
  810.  
  811.     qglDisable (GL_BLEND);
  812.     qglEnable (GL_TEXTURE_2D);
  813.     qglEnable (GL_ALPHA_TEST);
  814.  
  815.     qglColor4f(1,1,1,1);
  816. }
  817.  
  818. //=======================================================================
  819.  
  820. int SignbitsForPlane (cplane_t *out)
  821. {
  822.     int    bits, j;
  823.  
  824.     // for fast box on planeside test
  825.  
  826.     bits = 0;
  827.     for (j=0 ; j<3 ; j++)
  828.     {
  829.         if (out->normal[j] < 0)
  830.             bits |= 1<<j;
  831.     }
  832.     return bits;
  833. }
  834.  
  835.  
  836. void R_SetFrustum (void)
  837. {
  838.     int        i;
  839.  
  840.     // rotate VPN right by FOV_X/2 degrees
  841.     RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_newrefdef.fov_x / 2 ) );
  842.     // rotate VPN left by FOV_X/2 degrees
  843.     RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_newrefdef.fov_x / 2 );
  844.     // rotate VPN up by FOV_X/2 degrees
  845.     RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_newrefdef.fov_y / 2 );
  846.     // rotate VPN down by FOV_X/2 degrees
  847.     RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_newrefdef.fov_y / 2 ) );
  848.  
  849.     for (i=0 ; i<4 ; i++)
  850.     {
  851.         frustum[i].type = PLANE_ANYZ;
  852.         frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
  853.         frustum[i].signbits = SignbitsForPlane (&frustum[i]);
  854.     }
  855. }
  856.  
  857. //=======================================================================
  858.  
  859. /*
  860. ===============
  861. R_SetupFrame
  862. ===============
  863. */
  864. void R_SetupFrame (void)
  865. {
  866.     int i;
  867.     mleaf_t    *leaf;
  868.  
  869.     r_framecount++;
  870.  
  871. // build the transformation matrix for the given view angles
  872.     VectorCopy (r_newrefdef.vieworg, r_origin);
  873.  
  874.     AngleVectors (r_newrefdef.viewangles, vpn, vright, vup);
  875.  
  876. // current viewcluster
  877.     if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
  878.     {
  879.         r_oldviewcluster = r_viewcluster;
  880.         r_oldviewcluster2 = r_viewcluster2;
  881.         leaf = Mod_PointInLeaf (r_origin, r_worldmodel);
  882.         r_viewcluster = r_viewcluster2 = leaf->cluster;
  883.  
  884.         // check above and below so crossing solid water doesn't draw wrong
  885.         if (!leaf->contents)
  886.         {    // look down a bit
  887.             vec3_t    temp;
  888.  
  889.             VectorCopy (r_origin, temp);
  890.             temp[2] -= 16;
  891.             leaf = Mod_PointInLeaf (temp, r_worldmodel);
  892.             if ( !(leaf->contents & CONTENTS_SOLID) &&
  893.                 (leaf->cluster != r_viewcluster2) )
  894.                 r_viewcluster2 = leaf->cluster;
  895.         }
  896.         else
  897.         {    // look up a bit
  898.             vec3_t    temp;
  899.  
  900.             VectorCopy (r_origin, temp);
  901.             temp[2] += 16;
  902.             leaf = Mod_PointInLeaf (temp, r_worldmodel);
  903.             if ( !(leaf->contents & CONTENTS_SOLID) &&
  904.                 (leaf->cluster != r_viewcluster2) )
  905.                 r_viewcluster2 = leaf->cluster;
  906.         }
  907.     }
  908.  
  909.     for (i=0 ; i<4 ; i++)
  910.         v_blend[i] = r_newrefdef.blend[i];
  911.  
  912.     c_brush_polys = 0;
  913.     c_alias_polys = 0;
  914.  
  915.     // clear out the portion of the screen that the NOWORLDMODEL defines
  916.     if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
  917.     {
  918.         qglEnable( GL_SCISSOR_TEST );
  919.         qglClearColor( 0.3, 0.3, 0.3, 1 );
  920.         qglScissor( r_newrefdef.x, vid.height - r_newrefdef.height - r_newrefdef.y, r_newrefdef.width, r_newrefdef.height );
  921.         qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  922.         qglClearColor( 1, 0, 0.5, 0.5 );
  923.         qglDisable( GL_SCISSOR_TEST );
  924.     }
  925. }
  926.  
  927.  
  928. void MYgluPerspective( GLdouble fovy, GLdouble aspect,
  929.              GLdouble zNear, GLdouble zFar )
  930. {
  931.     GLdouble xmin, xmax, ymin, ymax;
  932.     
  933.     ymax = zNear * tan( fovy * M_PI / 360.0 );
  934.     ymin = -ymax;
  935.     
  936.     xmin = ymin * aspect;
  937.     xmax = ymax * aspect;
  938.     
  939.     xmin += -( 2 * gl_state.camera_separation ) / zNear;
  940.     xmax += -( 2 * gl_state.camera_separation ) / zNear;
  941.     
  942.     qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
  943. }
  944.  
  945.  
  946. /*
  947. =============
  948. R_SetupGL
  949. =============
  950. */
  951. void R_SetupGL (void)
  952. {
  953.     float    screenaspect;
  954.     int        x, x2, y2, y, w, h;
  955.  
  956.     //
  957.     // set up viewport
  958.     //
  959.     x = floor(r_newrefdef.x * vid.width / vid.width);
  960.     x2 = ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width);
  961.     y = floor(vid.height - r_newrefdef.y * vid.height / vid.height);
  962.     y2 = ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height);
  963.  
  964.     w = x2 - x;
  965.     h = y - y2;
  966.  
  967.     qglViewport (x, y2, w, h);
  968.  
  969.     //
  970.     // set up projection matrix
  971.     //
  972.     screenaspect = (float)r_newrefdef.width/r_newrefdef.height;
  973.     qglMatrixMode(GL_PROJECTION);
  974.     qglLoadIdentity ();
  975.     MYgluPerspective (r_newrefdef.fov_y, screenaspect, 4, 128000);
  976.  
  977.     qglCullFace(GL_FRONT);
  978.  
  979.     qglMatrixMode(GL_MODELVIEW);
  980.     qglLoadIdentity ();
  981.  
  982.     qglRotatef (-90, 1, 0, 0);        // put Z going up
  983.     qglRotatef (90,  0, 0, 1);        // put Z going up
  984.     qglRotatef (-r_newrefdef.viewangles[2], 1, 0, 0);
  985.     qglRotatef (-r_newrefdef.viewangles[0], 0, 1, 0);
  986.     qglRotatef (-r_newrefdef.viewangles[1], 0, 0, 1);
  987.     qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]);
  988.  
  989. //    if ( gl_state.camera_separation != 0 && gl_state.stereo_enabled )
  990. //        qglTranslatef ( gl_state.camera_separation, 0, 0 );
  991.  
  992.     qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
  993.  
  994.     //
  995.     // set drawing parms
  996.     //
  997.     if (gl_cull->value)
  998.         qglEnable(GL_CULL_FACE);
  999.     else
  1000.         qglDisable(GL_CULL_FACE);
  1001.  
  1002. // CDawg - start 
  1003.     if (r_newrefdef.viewangles[2]) 
  1004.         qglEnable(GL_BLEND); 
  1005.     else 
  1006.         qglDisable(GL_BLEND); 
  1007. // CDawg - end 
  1008.  
  1009. //qglDisable(GL_BLEND); //CDawg <-- comment this line. 
  1010.  
  1011.     qglDisable(GL_ALPHA_TEST);
  1012.     qglEnable(GL_DEPTH_TEST);
  1013. }
  1014.  
  1015. /*
  1016. =============
  1017. R_Clear
  1018. =============
  1019. */
  1020. void R_Clear (void)
  1021. {
  1022.     if (gl_clear->value)
  1023.         qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1024.     else
  1025.         qglClear (GL_DEPTH_BUFFER_BIT);
  1026.  
  1027.     gldepthmin = 0;
  1028.     gldepthmax = 1;
  1029.     qglDepthFunc (GL_LEQUAL);
  1030.  
  1031.     qglDepthRange (gldepthmin, gldepthmax);
  1032.  
  1033. }
  1034.  
  1035. void R_Flash( void )
  1036. {
  1037.     R_PolyBlend ();
  1038. }
  1039.  
  1040. /*
  1041. ================
  1042. R_RenderView
  1043.  
  1044. r_newrefdef must be set before the first call
  1045. ================
  1046. */
  1047. void R_RenderView (refdef_t *fd)
  1048. {
  1049.  
  1050.     GLfloat colors[4] = {(GLfloat) 0.3, (GLfloat) 0.3, (GLfloat) 0.3, (GLfloat) 0.1};
  1051.     
  1052.     if (r_norefresh->value)
  1053.         return;
  1054.  
  1055.     r_newrefdef = *fd;
  1056.  
  1057.     if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
  1058.         Com_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
  1059.  
  1060.     if (r_speeds->value)
  1061.     {
  1062.         c_brush_polys = 0;
  1063.         c_alias_polys = 0;
  1064.     }
  1065.     
  1066.  
  1067.     R_PushDlights ();
  1068.     R_PushStains ();
  1069.  
  1070.     if (gl_finish->value)
  1071.         qglFinish ();
  1072.  
  1073.     R_SetupFrame ();
  1074.  
  1075.     R_SetFrustum ();
  1076.  
  1077.     R_SetupGL ();
  1078.  
  1079.     R_MarkLeaves ();    // done here so we know if we're in water
  1080.  
  1081.     //qglFogi(GL_FOG_MODE, GL_LINEAR);
  1082.     //qglFogfv(GL_FOG_COLOR, colors);
  1083.     //qglFogf(GL_FOG_START, 50.0);
  1084.     //qglFogf(GL_FOG_END, 1500.0);
  1085.     //qglFogf(GL_FOG_DENSITY, 0.02);
  1086.     //qglEnable(GL_FOG);
  1087.  
  1088.     R_DrawWorld ();
  1089.  
  1090.     R_DrawEntitiesOnList ();
  1091.  
  1092.     R_DrawAlphaSurfaces ();
  1093.  
  1094.     R_RenderDlights ();
  1095.  
  1096.     R_DrawParticles ();
  1097.  
  1098.     R_Flash();
  1099.  
  1100.     if (r_speeds->value)
  1101.     {
  1102.         Com_Printf ( "%4i wpoly %4i epoly %i tex %i lmaps\n",
  1103.             c_brush_polys, 
  1104.             c_alias_polys, 
  1105.             c_visible_textures, 
  1106.             c_visible_lightmaps); 
  1107.     }
  1108.     //qglDisable(GL_FOG);
  1109. }
  1110.  
  1111.  
  1112. void    R_SetGL2D (void)
  1113. {
  1114.     // set 2D virtual screen size
  1115.     qglViewport (0,0, vid.width, vid.height);
  1116.     qglMatrixMode(GL_PROJECTION);
  1117.     qglLoadIdentity ();
  1118.     qglOrtho  (0, vid.width, vid.height, 0, -99999, 99999);
  1119.     qglMatrixMode(GL_MODELVIEW);
  1120.     qglLoadIdentity ();
  1121.     qglDisable (GL_DEPTH_TEST);
  1122.     qglDisable (GL_CULL_FACE);
  1123.     qglDisable (GL_BLEND);
  1124.     qglEnable (GL_ALPHA_TEST);
  1125.     qglColor4f (1,1,1,1);
  1126. }
  1127.  
  1128. static void GL_DrawColoredStereoLinePair( float r, float g, float b, float y )
  1129. {
  1130.     qglColor3f( r, g, b );
  1131.     qglVertex2f( 0, y );
  1132.     qglVertex2f( vid.width, y );
  1133.     qglColor3f( 0, 0, 0 );
  1134.     qglVertex2f( 0, y + 1 );
  1135.     qglVertex2f( vid.width, y + 1 );
  1136. }
  1137.  
  1138. static void GL_DrawStereoPattern( void )
  1139. {
  1140.     int i;
  1141.  
  1142.     if ( !( gl_config.renderer & GL_RENDERER_INTERGRAPH ) )
  1143.         return;
  1144.  
  1145.     if ( !gl_state.stereo_enabled )
  1146.         return;
  1147.  
  1148.     R_SetGL2D();
  1149.  
  1150.     qglDrawBuffer( GL_BACK_LEFT );
  1151.  
  1152.     for ( i = 0; i < 20; i++ )
  1153.     {
  1154.         qglBegin( GL_LINES );
  1155.             GL_DrawColoredStereoLinePair( 1, 0, 0, 0 );
  1156.             GL_DrawColoredStereoLinePair( 1, 0, 0, 2 );
  1157.             GL_DrawColoredStereoLinePair( 1, 0, 0, 4 );
  1158.             GL_DrawColoredStereoLinePair( 1, 0, 0, 6 );
  1159.             GL_DrawColoredStereoLinePair( 0, 1, 0, 8 );
  1160.             GL_DrawColoredStereoLinePair( 1, 1, 0, 10);
  1161.             GL_DrawColoredStereoLinePair( 1, 1, 0, 12);
  1162.             GL_DrawColoredStereoLinePair( 0, 1, 0, 14);
  1163.         qglEnd();
  1164.         
  1165.         GLimp_EndFrame();
  1166.     }
  1167. }
  1168.  
  1169.  
  1170. /*
  1171. ====================
  1172. R_SetLightLevel
  1173.  
  1174. ====================
  1175. */
  1176. void R_SetLightLevel (void)
  1177. {
  1178.     vec3_t        shadelight;
  1179.  
  1180.     if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
  1181.         return;
  1182.  
  1183.     // save off light value for server to look at (BIG HACK!)
  1184.  
  1185.     R_LightPoint (r_newrefdef.vieworg, shadelight);
  1186.  
  1187.     // pick the greatest component, which should be the same
  1188.     // as the mono value returned by software
  1189.     if (shadelight[0] > shadelight[1])
  1190.     {
  1191.         if (shadelight[0] > shadelight[2])
  1192.             r_lightlevel->value = 150*shadelight[0];
  1193.         else
  1194.             r_lightlevel->value = 150*shadelight[2];
  1195.     }
  1196.     else
  1197.     {
  1198.         if (shadelight[1] > shadelight[2])
  1199.             r_lightlevel->value = 150*shadelight[1];
  1200.         else
  1201.             r_lightlevel->value = 150*shadelight[2];
  1202.     }
  1203.  
  1204. }
  1205.  
  1206. /*
  1207. @@@@@@@@@@@@@@@@@@@@@
  1208. R_RenderFrame
  1209.  
  1210. @@@@@@@@@@@@@@@@@@@@@
  1211. */
  1212. void R_RenderFrame (refdef_t *fd)
  1213. {
  1214.     R_RenderView( fd );
  1215.     R_SetLightLevel ();
  1216.     R_SetGL2D ();
  1217. }
  1218.  
  1219.  
  1220. void R_Register( void )
  1221. {
  1222.     r_lefthand = Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
  1223.     r_norefresh = Cvar_Get ("r_norefresh", "0", 0);
  1224.     r_fullbright = Cvar_Get ("r_fullbright", "0", 0);
  1225.     r_drawentities = Cvar_Get ("r_drawentities", "1", 0);
  1226.     r_drawworld = Cvar_Get ("r_drawworld", "1", 0);
  1227.     r_novis = Cvar_Get ("r_novis", "0", 0);
  1228.     r_nocull = Cvar_Get ("r_nocull", "0", 0);
  1229.     r_lerpmodels = Cvar_Get ("r_lerpmodels", "1", 0);
  1230.     r_speeds = Cvar_Get ("r_speeds", "0", 0);
  1231.  
  1232.     r_lightlevel = Cvar_Get ("r_lightlevel", "0", 0);
  1233.  
  1234.     gl_nosubimage = Cvar_Get( "gl_nosubimage", "0", 0 );
  1235.     gl_allow_software = Cvar_Get( "gl_allow_software", "0", 0 );
  1236.  
  1237.     gl_particle_min_size = Cvar_Get( "gl_particle_min_size", "2", CVAR_ARCHIVE );
  1238.     gl_particle_max_size = Cvar_Get( "gl_particle_max_size", "40", CVAR_ARCHIVE );
  1239.     gl_particle_size = Cvar_Get( "gl_particle_size", "40", CVAR_ARCHIVE );
  1240.     gl_particle_att_a = Cvar_Get( "gl_particle_att_a", "0.01", CVAR_ARCHIVE );
  1241.     gl_particle_att_b = Cvar_Get( "gl_particle_att_b", "0.0", CVAR_ARCHIVE );
  1242.     gl_particle_att_c = Cvar_Get( "gl_particle_att_c", "0.01", CVAR_ARCHIVE );
  1243.  
  1244.     gl_modulate = Cvar_Get ("gl_modulate", "2", CVAR_ARCHIVE );
  1245.     gl_log = Cvar_Get( "gl_log", "0", 0 );
  1246.     gl_bitdepth = Cvar_Get( "gl_bitdepth", "0", 0 );
  1247.     gl_mode = Cvar_Get( "gl_mode", "3", CVAR_ARCHIVE );
  1248.     gl_lightmap = Cvar_Get ("gl_lightmap", "0", 0);
  1249.     gl_shadows = Cvar_Get ("gl_shadows", "0", CVAR_ARCHIVE );
  1250.     gl_dynamic = Cvar_Get ("gl_dynamic", "1", 0);
  1251.     gl_nobind = Cvar_Get ("gl_nobind", "0", 0);
  1252.     gl_round_down = Cvar_Get ("gl_round_down", "1", 0);
  1253.     gl_picmip = Cvar_Get ("gl_picmip", "0", 0);
  1254.     gl_skymip = Cvar_Get ("gl_skymip", "0", 0);
  1255.     gl_showtris = Cvar_Get ("gl_showtris", "0", 0);
  1256.     gl_finish = Cvar_Get ("gl_finish", "0", CVAR_ARCHIVE);
  1257.     gl_clear = Cvar_Get ("gl_clear", "0", 0);
  1258.     gl_cull = Cvar_Get ("gl_cull", "1", 0);
  1259.     gl_polyblend = Cvar_Get ("gl_polyblend", "1", 0);
  1260.     gl_flashblend = Cvar_Get ("gl_flashblend", "0", 0);
  1261.     gl_playermip = Cvar_Get ("gl_playermip", "0", 0);
  1262.     gl_monolightmap = Cvar_Get( "gl_monolightmap", "0", 0 );
  1263.     gl_driver = Cvar_Get( "gl_driver", "opengl32", CVAR_ARCHIVE );
  1264.     gl_texturemode = Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE );
  1265.     gl_texturealphamode = Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE );
  1266.     gl_texturesolidmode = Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE );
  1267.     gl_lockpvs = Cvar_Get( "gl_lockpvs", "0", 0 );
  1268.  
  1269.     gl_vertex_arrays = Cvar_Get( "gl_vertex_arrays", "0", CVAR_ARCHIVE );
  1270.  
  1271.     gl_ext_swapinterval = Cvar_Get( "gl_ext_swapinterval", "1", CVAR_ARCHIVE );
  1272.     gl_ext_palettedtexture = Cvar_Get( "gl_ext_palettedtexture", "0", CVAR_ARCHIVE );
  1273.     gl_ext_multitexture = Cvar_Get( "gl_ext_multitexture", "1", CVAR_ARCHIVE );
  1274.     gl_ext_pointparameters = Cvar_Get( "gl_ext_pointparameters", "0", CVAR_ARCHIVE );
  1275.     gl_ext_compiled_vertex_array = Cvar_Get( "gl_ext_compiled_vertex_array", "1", CVAR_ARCHIVE );
  1276.  
  1277.     gl_drawbuffer = Cvar_Get( "gl_drawbuffer", "GL_BACK", 0 );
  1278.     gl_swapinterval = Cvar_Get( "gl_swapinterval", "1", CVAR_ARCHIVE );
  1279.  
  1280.     gl_saturatelighting = Cvar_Get( "gl_saturatelighting", "0", 0 );
  1281.  
  1282.     gl_3dlabs_broken = Cvar_Get( "gl_3dlabs_broken", "1", CVAR_ARCHIVE );
  1283.  
  1284.     vid_fullscreen = Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
  1285.     vid_gamma = Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
  1286.     vid_ref = Cvar_Get( "vid_ref", "gl", CVAR_ARCHIVE );
  1287.  
  1288.     Cmd_AddCommand( "imagelist", GL_ImageList_f );
  1289.     Cmd_AddCommand( "screenshot", GL_ScreenShot_f );
  1290.     Cmd_AddCommand( "modellist", Mod_Modellist_f );
  1291.     Cmd_AddCommand( "gl_strings", GL_Strings_f );
  1292. }
  1293.  
  1294. /*
  1295. ==================
  1296. R_SetMode
  1297. ==================
  1298. */
  1299. qboolean R_SetMode (void)
  1300. {
  1301.     rserr_t err;
  1302.     qboolean fullscreen;
  1303.  
  1304.     if ( vid_fullscreen->modified && !gl_config.allow_cds )
  1305.     {
  1306.         Com_Printf ("R_SetMode() - CDS not allowed with this driver\n" );
  1307.         Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value );
  1308.         vid_fullscreen->modified = false;
  1309.     }
  1310.  
  1311.     fullscreen = vid_fullscreen->value;
  1312.  
  1313.     vid_fullscreen->modified = false;
  1314.     gl_mode->modified = false;
  1315.  
  1316.     if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, fullscreen ) ) == rserr_ok )
  1317.     {
  1318.         gl_state.prev_mode = gl_mode->value;
  1319.     }
  1320.     else
  1321.     {
  1322.         if ( err == rserr_invalid_fullscreen )
  1323.         {
  1324.             Cvar_SetValue( "vid_fullscreen", 0);
  1325.             vid_fullscreen->modified = false;
  1326.             Com_Printf ("ref_gl::R_SetMode() - fullscreen unavailable in this mode\n" );
  1327.             if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, false ) ) == rserr_ok )
  1328.                 return true;
  1329.         }
  1330.         else if ( err == rserr_invalid_mode )
  1331.         {
  1332.             Cvar_SetValue( "gl_mode", gl_state.prev_mode );
  1333.             gl_mode->modified = false;
  1334.             Com_Printf ("ref_gl::R_SetMode() - invalid mode\n" );
  1335.         }
  1336.  
  1337.         // try setting it back to something safe
  1338.         if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_state.prev_mode, false ) ) != rserr_ok )
  1339.         {
  1340.             Com_Printf ("ref_gl::R_SetMode() - could not revert to safe mode\n" );
  1341.             return false;
  1342.         }
  1343.     }
  1344.     return true;
  1345. }
  1346.  
  1347. /*
  1348. ===============
  1349. R_Init
  1350. ===============
  1351. */
  1352. int R_Init( void *hinstance, void *hWnd )
  1353. {    
  1354.     char renderer_buffer[1000];
  1355.     char vendor_buffer[1000];
  1356.     int        err;
  1357.     int        j;
  1358.     extern float r_turbsin[256];
  1359.  
  1360.     for ( j = 0; j < 256; j++ )
  1361.     {
  1362.         r_turbsin[j] *= 0.5;
  1363.     }
  1364.  
  1365.     Com_Printf ("ref_gl version: "REF_VERSION"\n");
  1366.  
  1367.     Draw_GetPalette ();
  1368.  
  1369.     R_Register();
  1370.  
  1371.     // initialize our QGL dynamic bindings
  1372.     if ( !QGL_Init( gl_driver->string ) )
  1373.     {
  1374.         QGL_Shutdown();
  1375.         Com_Printf ("ref_gl::R_Init() - could not load \"%s\"\n", gl_driver->string );
  1376.         return -1;
  1377.     }
  1378.  
  1379.     // initialize OS-specific parts of OpenGL
  1380.     if ( !GLimp_Init( hinstance, hWnd ) )
  1381.     {
  1382.         QGL_Shutdown();
  1383.         return -1;
  1384.     }
  1385.  
  1386.     // set our "safe" modes
  1387.     gl_state.prev_mode = 3;
  1388.  
  1389.     // create the window and set up the context
  1390.     if ( !R_SetMode () )
  1391.     {
  1392.         QGL_Shutdown();
  1393.         Com_Printf ("ref_gl::R_Init() - could not R_SetMode()\n" );
  1394.         return -1;
  1395.     }
  1396.  
  1397.     VID_MenuInit();
  1398.  
  1399.     /*
  1400.     ** get our various GL strings
  1401.     */
  1402.     gl_config.vendor_string = qglGetString (GL_VENDOR);
  1403.     Com_Printf ("GL_VENDOR: %s\n", gl_config.vendor_string );
  1404.     gl_config.renderer_string = qglGetString (GL_RENDERER);
  1405.     Com_Printf ("GL_RENDERER: %s\n", gl_config.renderer_string );
  1406.     gl_config.version_string = qglGetString (GL_VERSION);
  1407.     Com_Printf ("GL_VERSION: %s\n", gl_config.version_string );
  1408.     gl_config.extensions_string = qglGetString (GL_EXTENSIONS);
  1409.     Com_Printf ("GL_EXTENSIONS: %s\n", gl_config.extensions_string );
  1410.  
  1411.     strcpy( renderer_buffer, gl_config.renderer_string );
  1412.     strlwr( renderer_buffer );
  1413.  
  1414.     strcpy( vendor_buffer, gl_config.vendor_string );
  1415.     strlwr( vendor_buffer );
  1416.  
  1417.     if ( strstr( renderer_buffer, "voodoo" ) )
  1418.     {
  1419.         if ( !strstr( renderer_buffer, "rush" ) )
  1420.             gl_config.renderer = GL_RENDERER_VOODOO;
  1421.         else
  1422.             gl_config.renderer = GL_RENDERER_VOODOO_RUSH;
  1423.     }
  1424.     else if ( strstr( vendor_buffer, "sgi" ) )
  1425.         gl_config.renderer = GL_RENDERER_SGI;
  1426.     else if ( strstr( renderer_buffer, "permedia" ) )
  1427.         gl_config.renderer = GL_RENDERER_PERMEDIA2;
  1428.     else if ( strstr( renderer_buffer, "glint" ) )
  1429.         gl_config.renderer = GL_RENDERER_GLINT_MX;
  1430.     else if ( strstr( renderer_buffer, "glzicd" ) )
  1431.         gl_config.renderer = GL_RENDERER_REALIZM;
  1432.     else if ( strstr( renderer_buffer, "gdi" ) )
  1433.         gl_config.renderer = GL_RENDERER_MCD;
  1434.     else if ( strstr( renderer_buffer, "pcx2" ) )
  1435.         gl_config.renderer = GL_RENDERER_PCX2;
  1436.     else if ( strstr( renderer_buffer, "verite" ) )
  1437.         gl_config.renderer = GL_RENDERER_RENDITION;
  1438.     else
  1439.         gl_config.renderer = GL_RENDERER_OTHER;
  1440.  
  1441.     if ( toupper( gl_monolightmap->string[1] ) != 'F' )
  1442.     {
  1443.         if ( gl_config.renderer == GL_RENDERER_PERMEDIA2 )
  1444.         {
  1445.             Cvar_Set( "gl_monolightmap", "A" );
  1446.             Com_Printf ("...using gl_monolightmap 'a'\n" );
  1447.         }
  1448.         else if ( gl_config.renderer & GL_RENDERER_POWERVR ) 
  1449.         {
  1450.             Cvar_Set( "gl_monolightmap", "0" );
  1451.         }
  1452.         else
  1453.         {
  1454.             Cvar_Set( "gl_monolightmap", "0" );
  1455.         }
  1456.     }
  1457.  
  1458.     // power vr can't have anything stay in the framebuffer, so
  1459.     // the screen needs to redraw the tiled background every frame
  1460.     if ( gl_config.renderer & GL_RENDERER_POWERVR ) 
  1461.     {
  1462.         Cvar_Set( "scr_drawall", "1" );
  1463.     }
  1464.     else
  1465.     {
  1466.         Cvar_Set( "scr_drawall", "0" );
  1467.     }
  1468.  
  1469. #ifdef __linux__
  1470.     Cvar_SetValue( "gl_finish", 1 );
  1471. #endif
  1472.  
  1473.     // MCD has buffering issues
  1474.     if ( gl_config.renderer == GL_RENDERER_MCD )
  1475.     {
  1476.         Cvar_SetValue( "gl_finish", 1 );
  1477.     }
  1478.  
  1479.     if ( gl_config.renderer & GL_RENDERER_3DLABS )
  1480.     {
  1481.         if ( gl_3dlabs_broken->value )
  1482.             gl_config.allow_cds = false;
  1483.         else
  1484.             gl_config.allow_cds = true;
  1485.     }
  1486.     else
  1487.     {
  1488.         gl_config.allow_cds = true;
  1489.     }
  1490.  
  1491.     if ( gl_config.allow_cds )
  1492.         Com_Printf ("...allowing CDS\n" );
  1493.     else
  1494.         Com_Printf ( "...disabling CDS\n" );
  1495.  
  1496.     /*
  1497.     ** grab extensions
  1498.     */
  1499.     if ( strstr( gl_config.extensions_string, "GL_EXT_compiled_vertex_array" ) || 
  1500.          strstr( gl_config.extensions_string, "GL_SGI_compiled_vertex_array" ) )
  1501.     {
  1502.         Com_Printf ("...enabling GL_EXT_compiled_vertex_array\n" );
  1503.         qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" );
  1504.         qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" );
  1505.     }
  1506.     else
  1507.     {
  1508.         Com_Printf ("...GL_EXT_compiled_vertex_array not found\n" );
  1509.     }
  1510.  
  1511. #ifdef _WIN32
  1512.     if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) )
  1513.     {
  1514.         qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" );
  1515.         Com_Printf ("...enabling WGL_EXT_swap_control\n" );
  1516.     }
  1517.     else
  1518.     {
  1519.         Com_Printf ("...WGL_EXT_swap_control not found\n" );
  1520.     }
  1521. #endif
  1522.  
  1523.     if ( strstr( gl_config.extensions_string, "GL_EXT_point_parameters" ) )
  1524.     {
  1525.         if ( gl_ext_pointparameters->value )
  1526.         {
  1527.             qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" );
  1528.             qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" );
  1529.             Com_Printf ("...using GL_EXT_point_parameters\n" );
  1530.         }
  1531.         else
  1532.         {
  1533.             Com_Printf ("...ignoring GL_EXT_point_parameters\n" );
  1534.         }
  1535.     }
  1536.     else
  1537.     {
  1538.         Com_Printf ("...GL_EXT_point_parameters not found\n" );
  1539.     }
  1540.  
  1541. #ifdef __linux__
  1542.     if ( strstr( gl_config.extensions_string, "3DFX_set_global_palette" ))
  1543.     {
  1544.         if ( gl_ext_palettedtexture->value )
  1545.         {
  1546.             Com_Printf ("...using 3DFX_set_global_palette\n" );
  1547.             qgl3DfxSetPaletteEXT = ( void ( APIENTRY * ) (GLuint *) )qwglGetProcAddress( "gl3DfxSetPaletteEXT" );
  1548.             qglColorTableEXT = Fake_glColorTableEXT;
  1549.         }
  1550.         else
  1551.         {
  1552.             Com_Printf ("...ignoring 3DFX_set_global_palette\n" );
  1553.         }
  1554.     }
  1555.     else
  1556.     {
  1557.         Com_Printf ("...3DFX_set_global_palette not found\n" );
  1558.     }
  1559. #endif
  1560.  
  1561.     if ( !qglColorTableEXT &&
  1562.         strstr( gl_config.extensions_string, "GL_EXT_paletted_texture" ) && 
  1563.         strstr( gl_config.extensions_string, "GL_EXT_shared_texture_palette" ) )
  1564.     {
  1565.         if ( gl_ext_palettedtexture->value )
  1566.         {
  1567.             Com_Printf ("...using GL_EXT_shared_texture_palette\n" );
  1568.             qglColorTableEXT = ( void ( APIENTRY * ) ( int, int, int, int, int, const void * ) ) qwglGetProcAddress( "glColorTableEXT" );
  1569.         }
  1570.         else
  1571.         {
  1572.             Com_Printf ("...ignoring GL_EXT_shared_texture_palette\n" );
  1573.         }
  1574.     }
  1575.     else
  1576.     {
  1577.         Com_Printf ("...GL_EXT_shared_texture_palette not found\n" );
  1578.     }
  1579.  
  1580.     if ( strstr( gl_config.extensions_string, "GL_ARB_multitexture" ) )
  1581.     {
  1582.         if ( gl_ext_multitexture->value )
  1583.         {
  1584.             Com_Printf ("...using GL_ARB_multitexture\n" );
  1585.             qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMultiTexCoord2fARB" );
  1586.             qglActiveTextureARB = ( void * ) qwglGetProcAddress( "glActiveTextureARB" );
  1587.             qglClientActiveTextureARB = ( void * ) qwglGetProcAddress( "glClientActiveTextureARB" );
  1588.             GL_TEXTURE0 = GL_TEXTURE0_ARB;
  1589.             GL_TEXTURE1 = GL_TEXTURE1_ARB;
  1590.         }
  1591.         else
  1592.         {
  1593.             Com_Printf ("...ignoring GL_ARB_multitexture\n" );
  1594.         }
  1595.     }
  1596.     else
  1597.     {
  1598.         Com_Printf ("...GL_ARB_multitexture not found\n" );
  1599.     }
  1600.  
  1601.     if ( strstr( gl_config.extensions_string, "GL_SGIS_multitexture" ) )
  1602.     {
  1603.         if ( qglActiveTextureARB )
  1604.         {
  1605.             Com_Printf ("...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n" );
  1606.         }
  1607.         else if ( gl_ext_multitexture->value )
  1608.         {
  1609.             Com_Printf ("...using GL_SGIS_multitexture\n" );
  1610.             qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMTexCoord2fSGIS" );
  1611.             qglSelectTextureSGIS = ( void * ) qwglGetProcAddress( "glSelectTextureSGIS" );
  1612.             GL_TEXTURE0 = GL_TEXTURE0_SGIS;
  1613.             GL_TEXTURE1 = GL_TEXTURE1_SGIS;
  1614.         }
  1615.         else
  1616.         {
  1617.             Com_Printf ("...ignoring GL_SGIS_multitexture\n" );
  1618.         }
  1619.     }
  1620.     else
  1621.     {
  1622.         Com_Printf ("...GL_SGIS_multitexture not found\n" );
  1623.     }
  1624.  
  1625.     GL_SetDefaultState();
  1626.  
  1627.     /*
  1628.     ** draw our stereo patterns
  1629.     */
  1630. #if 0 // commented out until H3D pays us the money they owe us
  1631.     GL_DrawStereoPattern();
  1632. #endif
  1633.  
  1634.     GL_InitImages ();
  1635.     Mod_Init ();
  1636.     R_InitParticleTexture ();
  1637.     Draw_InitLocal ();
  1638.  
  1639.     err = qglGetError();
  1640.     if ( err != GL_NO_ERROR )
  1641.         Com_Printf ("glGetError() = 0x%x\n", err);
  1642.  
  1643.     return 0;
  1644. }
  1645.  
  1646. /*
  1647. ===============
  1648. R_Shutdown
  1649. ===============
  1650. */
  1651. void R_Shutdown (void)
  1652. {
  1653.     Cmd_RemoveCommand ("modellist");
  1654.     Cmd_RemoveCommand ("screenshot");
  1655.     Cmd_RemoveCommand ("imagelist");
  1656.     Cmd_RemoveCommand ("gl_strings");
  1657.  
  1658.     Mod_FreeAll ();
  1659.  
  1660.     GL_ShutdownImages ();
  1661.  
  1662.     /*
  1663.     ** shut down OS specific OpenGL stuff like contexts, etc.
  1664.     */
  1665.     GLimp_Shutdown();
  1666.  
  1667.     /*
  1668.     ** shutdown our QGL subsystem
  1669.     */
  1670.     QGL_Shutdown();
  1671. }
  1672.  
  1673.  
  1674.  
  1675. /*
  1676. @@@@@@@@@@@@@@@@@@@@@
  1677. R_BeginFrame
  1678. @@@@@@@@@@@@@@@@@@@@@
  1679. */
  1680. void R_BeginFrame( float camera_separation )
  1681. {
  1682.  
  1683.     gl_state.camera_separation = camera_separation;
  1684.  
  1685.     /*
  1686.     ** change modes if necessary
  1687.     */
  1688.     if ( gl_mode->modified || vid_fullscreen->modified )
  1689.     {    // FIXME: only restart if CDS is required
  1690.         cvar_t    *ref;
  1691.  
  1692.         ref = Cvar_Get ("vid_ref", "gl", 0);
  1693.         ref->modified = true;
  1694.     }
  1695.  
  1696.     if ( gl_log->modified )
  1697.     {
  1698.         GLimp_EnableLogging( gl_log->value );
  1699.         gl_log->modified = false;
  1700.     }
  1701.  
  1702.     if ( gl_log->value )
  1703.     {
  1704.         GLimp_LogNewFrame();
  1705.     }
  1706.  
  1707.     /*
  1708.     ** update 3Dfx gamma -- it is expected that a user will do a vid_restart
  1709.     ** after tweaking this value
  1710.     */
  1711.     if ( vid_gamma->modified )
  1712.     {
  1713.         vid_gamma->modified = false;
  1714.  
  1715.         if ( gl_config.renderer & ( GL_RENDERER_VOODOO ) )
  1716.         {
  1717.             char envbuffer[1024];
  1718.             float g;
  1719.  
  1720.             g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F;
  1721.             Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g );
  1722.             putenv( envbuffer );
  1723.             Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g );
  1724.             putenv( envbuffer );
  1725.         }
  1726.     }
  1727.  
  1728.     GLimp_BeginFrame( camera_separation );
  1729.  
  1730.     /*
  1731.     ** go into 2D mode
  1732.     */
  1733.     R_SetGL2D ();
  1734.  
  1735.     /*
  1736.     ** draw buffer stuff
  1737.     */
  1738.     if ( gl_drawbuffer->modified )
  1739.     {
  1740.         gl_drawbuffer->modified = false;
  1741.  
  1742.         if ( gl_state.camera_separation == 0 || !gl_state.stereo_enabled )
  1743.         {
  1744.             if ( Q_stricmp( gl_drawbuffer->string, "GL_FRONT" ) == 0 )
  1745.                 qglDrawBuffer( GL_FRONT );
  1746.             else
  1747.                 qglDrawBuffer( GL_BACK );
  1748.         }
  1749.     }
  1750.  
  1751.     /*
  1752.     ** texturemode stuff
  1753.     */
  1754.     if ( gl_texturemode->modified )
  1755.     {
  1756.         GL_TextureMode( gl_texturemode->string );
  1757.         gl_texturemode->modified = false;
  1758.     }
  1759.  
  1760.     if ( gl_texturealphamode->modified )
  1761.     {
  1762.         GL_TextureAlphaMode( gl_texturealphamode->string );
  1763.         gl_texturealphamode->modified = false;
  1764.     }
  1765.  
  1766.     if ( gl_texturesolidmode->modified )
  1767.     {
  1768.         GL_TextureSolidMode( gl_texturesolidmode->string );
  1769.         gl_texturesolidmode->modified = false;
  1770.     }
  1771.  
  1772.     /*
  1773.     ** swapinterval stuff
  1774.     */
  1775.     GL_UpdateSwapInterval();
  1776.  
  1777.     //
  1778.     // clear screen if desired
  1779.     //
  1780.     R_Clear ();
  1781. }
  1782.  
  1783. /*
  1784. =============
  1785. R_AppActivate
  1786. =============
  1787. */
  1788. void R_AppActivate( qboolean active )
  1789. {
  1790.     GLimp_AppActivate (active);
  1791. }
  1792.  
  1793. /*
  1794. =============
  1795. R_EndFrame
  1796. =============
  1797. */
  1798. void R_EndFrame (void)
  1799. {
  1800.      GLimp_EndFrame ();
  1801. }
  1802.  
  1803. /*
  1804. =============
  1805. R_SetPalette
  1806. =============
  1807. */
  1808. unsigned r_rawpalette[256];
  1809.  
  1810. void R_SetPalette ( const unsigned char *palette)
  1811. {
  1812.     int        i;
  1813.  
  1814.     byte *rp = ( byte * ) r_rawpalette;
  1815.  
  1816.     if ( palette )
  1817.     {
  1818.         for ( i = 0; i < 256; i++ )
  1819.         {
  1820.             rp[i*4+0] = palette[i*3+0];
  1821.             rp[i*4+1] = palette[i*3+1];
  1822.             rp[i*4+2] = palette[i*3+2];
  1823.             rp[i*4+3] = 0xff;
  1824.         }
  1825.     }
  1826.     else
  1827.     {
  1828.         for ( i = 0; i < 256; i++ )
  1829.         {
  1830.             rp[i*4+0] = d_8to24table[i] & 0xff;
  1831.             rp[i*4+1] = ( d_8to24table[i] >> 8 ) & 0xff;
  1832.             rp[i*4+2] = ( d_8to24table[i] >> 16 ) & 0xff;
  1833.             rp[i*4+3] = 0xff;
  1834.         }
  1835.     }
  1836.     GL_SetTexturePalette( r_rawpalette );
  1837.  
  1838.     qglClearColor (0,0,0,0);
  1839.     qglClear (GL_COLOR_BUFFER_BIT);
  1840.     qglClearColor (1,0, 0.5 , 0.5);
  1841. }
  1842.  
  1843. /*
  1844. ** R_DrawBeam
  1845. */
  1846. void R_DrawBeam( entity_t *e )
  1847. {
  1848. #define NUM_BEAM_SEGS 6
  1849.  
  1850.     int    i;
  1851.     float r, g, b;
  1852.  
  1853.     vec3_t perpvec;
  1854.     vec3_t direction, normalized_direction;
  1855.     vec3_t    start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
  1856.     vec3_t oldorigin, origin;
  1857.  
  1858.     oldorigin[0] = e->oldorigin[0];
  1859.     oldorigin[1] = e->oldorigin[1];
  1860.     oldorigin[2] = e->oldorigin[2];
  1861.  
  1862.     origin[0] = e->origin[0];
  1863.     origin[1] = e->origin[1];
  1864.     origin[2] = e->origin[2];
  1865.  
  1866.     normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
  1867.     normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
  1868.     normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
  1869.  
  1870.     if ( VectorNormalize( normalized_direction ) == 0 )
  1871.         return;
  1872.  
  1873.     PerpendicularVector( perpvec, normalized_direction );
  1874.     VectorScale( perpvec, e->frame / 2, perpvec );
  1875.  
  1876.     for ( i = 0; i < 6; i++ )
  1877.     {
  1878.         RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
  1879.         VectorAdd( start_points[i], origin, start_points[i] );
  1880.         VectorAdd( start_points[i], direction, end_points[i] );
  1881.     }
  1882.  
  1883.     qglDisable( GL_TEXTURE_2D );
  1884.     qglEnable( GL_BLEND );
  1885.     qglDepthMask( GL_FALSE );
  1886.  
  1887.     r = ( d_8to24table[e->skinnum & 0xFF] ) & 0xFF;
  1888.     g = ( d_8to24table[e->skinnum & 0xFF] >> 8 ) & 0xFF;
  1889.     b = ( d_8to24table[e->skinnum & 0xFF] >> 16 ) & 0xFF;
  1890.  
  1891.     r *= 1/255.0F;
  1892.     g *= 1/255.0F;
  1893.     b *= 1/255.0F;
  1894.  
  1895.     qglColor4f( r, g, b, e->alpha );
  1896.  
  1897.     qglBegin( GL_TRIANGLE_STRIP );
  1898.     for ( i = 0; i < NUM_BEAM_SEGS; i++ )
  1899.     {
  1900.         qglVertex3fv( start_points[i] );
  1901.         qglVertex3fv( end_points[i] );
  1902.         qglVertex3fv( start_points[(i+1)%NUM_BEAM_SEGS] );
  1903.         qglVertex3fv( end_points[(i+1)%NUM_BEAM_SEGS] );
  1904.     }
  1905.     qglEnd();
  1906.  
  1907.     qglEnable( GL_TEXTURE_2D );
  1908.     qglDisable( GL_BLEND );
  1909.     qglDepthMask( GL_TRUE );
  1910. }
  1911.  
  1912. // glow rendering - this was originally in gl_rmain.c
  1913. void R_RenderGlowEffects (void)
  1914. {
  1915.     int i, j, k;
  1916.     vec3_t v;
  1917.  
  1918.     // replace this with your own fog stuff if you're using fog
  1919. //    if (gl_fogenabled)
  1920. //        glDisable (GL_FOG);
  1921.  
  1922.     qglDepthMask (0);
  1923.     qglDisable (GL_TEXTURE_2D);
  1924.     qglShadeModel (GL_SMOOTH);
  1925.     qglEnable (GL_BLEND);
  1926.     qglBlendFunc (GL_ONE, GL_ONE);
  1927.  
  1928.     for (k = 0; k < num_glows; k++)
  1929.     {
  1930.         qglBegin (GL_TRIANGLE_FAN);
  1931.         qglColor3f (glow_effects[k].red, glow_effects[k].green, glow_effects[k].blue);
  1932.  
  1933.         for (i = 0; i < 3; i++)
  1934.             v[i] = glow_effects[k].origin[i] - vpn[i] * glow_effects[k].radius;
  1935.  
  1936.         qglVertex3fv (v);
  1937.         qglColor3f (0,0,0);
  1938.  
  1939.         for (i = 16; i >= 0; i--)
  1940.         {
  1941.             for (j = 0; j < 3; j++)
  1942.                 v[j] = glow_effects[k].origin[j] + vright[j] * glowcos[i] * 
  1943.                     glow_effects[k].radius + vup[j] * glowsin[i] * glow_effects[k].radius;
  1944.  
  1945.             qglVertex3fv (v);
  1946.         }
  1947.  
  1948.         qglEnd ();
  1949.     }
  1950.  
  1951.     qglColor3f (1,1,1);
  1952.     qglDisable (GL_BLEND);
  1953.     qglEnable (GL_TEXTURE_2D);
  1954.     qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1955.     qglDepthMask (1);
  1956.  
  1957.     // replace this with your own fog stuff if you're using fog
  1958. //    if (gl_fogenabled)
  1959. //        glEnable (GL_FOG);
  1960. }
  1961.  
  1962.  
  1963. void R_AddGlowEffect (float red, float green, float blue, float radius, vec3_t origin)
  1964. {
  1965.     glow_effects[num_glows].red = red;
  1966.     glow_effects[num_glows].green = green;
  1967.     glow_effects[num_glows].blue = blue;
  1968.  
  1969.     glow_effects[num_glows].radius = radius;
  1970.  
  1971.     glow_effects[num_glows].origin[0] = origin[0];
  1972.     glow_effects[num_glows].origin[1] = origin[1];
  1973.     glow_effects[num_glows].origin[2] = origin[2];
  1974.  
  1975.     num_glows++;
  1976. }
  1977.